package org.example.util;

import okhttp3.*;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

public class HttpUtils {

    private static OkHttpClient client = new OkHttpClient();

    private String url;
    private String method = "GET";
    private Map<String, String> headers = new HashMap<>();
    private Map<String, Object> params = new HashMap<>();
    private String body;
    private Type responseType;

    public HttpUtils url(String url) {
        this.url = url;
        return this;
    }

    public HttpUtils headers(Map<String, String> headers) {
        this.headers.putAll(headers);
        return this;
    }

    public HttpUtils header(String name, String value) {
        this.headers.put(name, value);
        return this;
    }

    public HttpUtils params(Map<String, Object> params) {
        this.params.putAll(params);
        return this;
    }

    public HttpUtils param(String name, Object value) {
        this.params.put(name, value);
        return this;
    }

    public HttpUtils body(String body) {
        this.body = body;
        return this;
    }

    public HttpUtils method(String method) {
        this.method = method;
        return this;
    }

    public HttpUtils responseType(Type type) {
        this.responseType = type;
        return this;
    }

    public <T> T execute() throws IOException {
        Request.Builder builder = new Request.Builder().url(url);
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            builder.addHeader(entry.getKey(), entry.getValue());
        }
        Request request;
        switch (method) {
            case "GET":
                request = builder.get().build();
                break;
            case "POST":
                RequestBody requestBody;
                if (params.isEmpty() && body != null) {
                    requestBody = RequestBody.create(MediaType.parse("application/json"), body);
                } else {
                    MultipartBody.Builder multipartBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
                    for (Map.Entry<String, Object> entry : params.entrySet()) {
                        if (entry.getValue() instanceof File) {
                            File file = (File) entry.getValue();
                            multipartBuilder.addFormDataPart(entry.getKey(), file.getName(), RequestBody.create(MediaType.parse("application/octet-stream"), file));
                        } else {
                            multipartBuilder.addFormDataPart(entry.getKey(), entry.getValue().toString());
                        }
                    }
                    if (body != null) {
                        multipartBuilder.addFormDataPart("body", body);
                    }
                    requestBody = multipartBuilder.build();
                }
                request = builder.post(requestBody).build();
                break;
            default:
                throw new IllegalArgumentException("Unsupported method: " + method);
        }
        Response response = client.newCall(request).execute();
        if (!response.isSuccessful()) {
            throw new IOException("Unexpected code " + response);
        }
        if (response.body() == null) {
            return null;
        }
        if (responseType != null) {
            //noinspection unchecked
            return JsonUtils.fromJson(response.body().string(), (Class<? extends T>) responseType);
        } else {
            return null;
        }
    }

    public static void main(String[] args) throws IOException {
        // get请求
        HttpUtils http = new HttpUtils();
        String result = http.url("http://127.0.0.1:8081/api/heartBeat")
                .param("id", 123)
                .param("name", "foo")
                .responseType(String.class)
                .execute();
        System.out.println(result);
    }
}
